package com.privated.work.utils;

import com.privated.work.exception.BusinessException;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;

/**
 * @Description
 * @Author JohnCoding
 * @Since 2020-11-02 14:00:02
 */
public class FileUtil {


    // 缓存文件头信息-文件头信息  用于校验强制修改后缀通过验证的木马行为 C#踩过的坑不能再踩

    public static final HashMap<String, String> mFileTypes = new HashMap<String, String>();

    static {
        // images
        mFileTypes.put("jpg", "FFD8FFE0");
        mFileTypes.put("png", "89504E47");
        mFileTypes.put("gif", "47494638");
        mFileTypes.put("tif", "49492A00");
        mFileTypes.put("bmp", "424D");
        // CAD
        mFileTypes.put("dwg", "41433130");
        mFileTypes.put("psd", "38425053");
        // 日记本
        mFileTypes.put("rtf", "7B5C727466");
        mFileTypes.put("xml", "3C3F786D6C");
        mFileTypes.put("html", "68746D6C3E");
        // 邮件
        mFileTypes.put("eml", "44656C69766572792D646174653A");
        mFileTypes.put("doc", "D0CF11E0");
        mFileTypes.put("mdb", "5374616E64617264204A");
        mFileTypes.put("ps", "252150532D41646F6265");
        mFileTypes.put("pdf", "255044462D312E");
        mFileTypes.put("docx", "504B0304");
        mFileTypes.put("rar", "52617221");
        mFileTypes.put("wav", "57415645");
        mFileTypes.put("avi", "41564920");
        mFileTypes.put("rm", "2E524D46");
        mFileTypes.put("mpg", "000001BA");
//        mFileTypes.put("mpg", "000001B3");
        mFileTypes.put("mov", "6D6F6F76");
        mFileTypes.put("asf", "3026B2758E66CF11");
        mFileTypes.put("mid", "4D546864");
        mFileTypes.put("gz", "1F8B08");
        mFileTypes.put("exe/dll", "4D5A9000");
        mFileTypes.put("txt", "75736167");
        mFileTypes.put("xlsx", "504B0304");
        mFileTypes.put("xls", "504B0304");
        mFileTypes.put("csv", "504B0304");
    }


    /***
     * 保存文件到服务器
     *
     * @param file
     * @return
     */
    public static boolean saveFile(MultipartFile file, String uploadPath) {
        File targetFile = new File(uploadPath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        // 判断文件是否为空
        if (!file.isEmpty()) {
            try {
                // 转存文件
                file.transferTo(targetFile);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }


    /**
     * 根据上传文件验证后缀
     *
     * @param file              验证的文件
     * @param verifySuffixes    验证的后缀
     */
    public static void verifyFileFormat(MultipartFile file, String... verifySuffixes) {
        if (file.isEmpty()) {
            //如果为空
            throw new BusinessException("-10009", "上传的文件不能为空");
        }
        String fileName = file.getOriginalFilename();
        String lastSpilt = StringUtil.getLastSpilt(fileName);
        int x = 0;
        for (String suffix : verifySuffixes) {
            if (!suffix.equals(lastSpilt)) {
                x ++;
            }
        }
        if(x == verifySuffixes.length){
            throw new BusinessException("-10010", "上传文件仅支持{0},请检查上传的文件格式是否正确！" , Arrays.toString(verifySuffixes));
        }
        //验证文件是否非法
        String fileHeader = getFileHeader(file);
        if (!mFileTypes.get(lastSpilt).equals(fileHeader)) {
            //匹配不上数据头文件
            throw new BusinessException("-10011","上传文件非法, 请检查");
        }
    }

    /**
     * 获取上传文件的文件头属性
     * @param file
     * @return
     */
    public static String getFileHeader(MultipartFile file) {
        InputStream is = null;
        String value = null;
        try {
            is = file.getInputStream();
            byte[] b = new byte[4];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        return value;
    }

    /**
     * 字节数组转字符窜
     * @param src
     * @return
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        String hv;
        for (int i = 0; i < src.length; i++) {
            hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        System.out.println(builder.toString());
        return builder.toString();
    }

}
